package com.zytlifeservice.service;

import com.zytlifeservice.controller.FileUploadController;
import com.zytlifeservice.domain.User;
import com.zytlifeservice.exception.StorageException;
import com.zytlifeservice.exception.UserException;
import com.zytlifeservice.properties.StorageProperties;
import com.zytlifeservice.repository.UserRepository;
import com.zytlifeservice.util.TextUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by MJS on 2017/4/25.
 */

@Service
public class FileUploadService {

    private static final Logger logger = LoggerFactory.getLogger(FileUploadService.class);

    @Value("${web.upload-path}")
    private String dirPath;

    @Autowired
    private StorageProperties storageProperties;

    @Autowired
    private UserRepository userRepository;

    /*初始化下载的文件仓库*/
    public void init() {
        String dirPath = storageProperties.getLocation();
        File dirFile = new File(dirPath);
        logger.info("初始化仓库path={}", dirFile.getAbsoluteFile());
        if (!dirFile.exists()) {
            if (!dirFile.mkdirs()) {
                throw new StorageException("fail to init file storage");
            }
        }
        File dirBaseIcon = new File(storageProperties.getBaseIconDir());
        if (!dirBaseIcon.exists()) {
            if (!dirBaseIcon.mkdirs()) {
                throw new StorageException("fail to init baseIcon storage");
            }
        }

        File dirHeadIcon = new File(storageProperties.getHeadIconDir());
        if (!dirHeadIcon.exists()) {
            if (!dirHeadIcon.mkdirs()) {
                throw new StorageException("fail to init headIcon storage");
            }
        }
    }

    /**
     * 存储文件    这里做一个区分，更具上传参数的不同，存储在不同的文件夹。
     *
     * @param userId
     * @param file
     * @return
     */
    public String store(String userId, MultipartFile file) {
        long parseLong = Long.parseLong(userId);
        User one = userRepository.findOne(parseLong);
        if (one == null) {
            throw new UserException("用户不存在", 100);
        }
        String originalFilename = file.getOriginalFilename();
        String path = "";
        if (originalFilename != null && !"".equalsIgnoreCase(originalFilename) && isImageFile(originalFilename)) {
            delFileIfExits("head_icon_" + userId);
            String fileName = "head_icon_" + userId + getFileType(originalFilename);
            String storeFile = storageProperties.getHeadIconDir() + File.separator + fileName;
            File outFile = new File(storeFile);
            try {
                FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(outFile));
                path = MvcUriComponentsBuilder.fromMethodName(FileUploadController.class, "serveFile", fileName).build().toString();
                logger.info("savePath={}" + path);
            } catch (IOException e) {
                e.printStackTrace();
                throw new UserException("上传失败", 100);
            }
        }
        return path;
    }

    public String storeBaseIcon(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        logger.info("baseIcon originalFileName = " + originalFilename);
        String path = "";
        if (originalFilename != null && !"".equalsIgnoreCase(originalFilename) && isImageFile(originalFilename)) {
            String fileName = "baseIcon_" + getTimeStamp() + "_" + originalFilename;
            String storeFilePath = storageProperties.getBaseIconDir() + File.separator + fileName;
            File outFile = new File(storeFilePath);
            logger.info("outFile=" + outFile.getAbsolutePath());
            try {
                FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(outFile));
                path = MvcUriComponentsBuilder.fromMethodName(FileUploadController.class, "serveBaseIconFile", fileName).build().toString();
                logger.info("savePath={}", path);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return path;
    }

    private String getTimeStamp() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        return sdf.format(new Date());
    }

    private void delFileIfExits(String fileName) {
        String[] img_type = new String[]{".jpg", ".jpeg", ".png", ".gif", ".bmp"};
        for (String type : img_type) {
            File file = new File(storageProperties.getLocation() + File.separator + fileName + type);
            logger.info("delete file ={}", file.getAbsoluteFile());
            if (file.exists()) {
                file.delete();
            }
        }
    }

    /**
     * 返回文件本地资源
     *
     * @param fileName
     * @return
     */
    public Resource loadAsResource(String fileName) {
        String dir = storageProperties.getHeadIconDir();
        String filePath = dir + File.separator + fileName;
        File file = new File(filePath);
        logger.info("本地地址={}", file.getAbsoluteFile());
        if (file.exists()) {
            try {
                Resource resource = new UrlResource(file.toURI());
                if (resource.exists() || resource.isReadable()) {
                    return resource;
                }
            } catch (MalformedURLException e) {
                throw new StorageException("can not read file");
            }
        }
        throw new StorageException("file not exits");
    }


    public Resource loadAsBaseIconResource(String fileName) {
        String dir = storageProperties.getBaseIconDir();
        String filePath = dir + File.separator + fileName;
        File file = new File(filePath);
        logger.info("localPath={}", file.getAbsolutePath());
        if (file.exists()) {
            try {
                Resource resource = new UrlResource(file.toURI());
                if (resource.exists() || resource.isReadable()) {
                    return resource;
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
                throw new StorageException("can not read file");
            }
        }
        throw new StorageException("file not exits");
    }

    private String getFileType(String fileName) {
        return fileName.indexOf(".") > 0 ? fileName.substring(fileName.lastIndexOf("."), fileName.length()) : "";
    }

    private boolean isImageFile(String fileName) {
        String[] img_type = new String[]{".jpg", ".jpeg", ".png", ".gif", ".bmp"};
        fileName = fileName.toLowerCase();
        for (String type : img_type) {
            if (fileName.endsWith(type)) {
                return true;
            }
        }
        return false;
    }

    public void delete(String path) {
        if (TextUtil.isEmpty(path)) {
            return;
        }
        String fileName = path.substring(path.lastIndexOf("/"));
        logger.info("deleteFileName = " + fileName);
        String filePath = storageProperties.getBaseIconDir() + File.separator + fileName;
        File file = new File(filePath);
        logger.info("delete Path={}" + file.getAbsolutePath());
        if (file.exists()) {
            logger.info("delete ={}", file.delete());
        }
    }
}
